module main(clk, mode, select, set, rst, stop, s_data, m_data, h_data, beep);
/*
 * clk 时钟信号
 * mode 增加mode_cnt（按钮）
 * select 增加select_cnt （按钮）
 * set 增加计数（按钮）
 * rst 复位信号
 * stop 手动关闭闹钟（按钮）
 * s_data m_data h_data 秒、分、时的显示输出
 * beep 闹钟输出--扬声器使能
 * Author: GWF
 */
 
input clk, mode, select, set, rst, stop;
output[7:0] s_data, m_data, h_data;
output reg beep;

reg rst1, rst2, en1, en2;	//rst1-时钟C1的复位信号 | rst2-闹钟C2的复位信号
reg mode_cnt;					//mode_cnt 主模式控制：0 时钟相关 | 1 闹钟相关
reg[1:0]  select_cnt;		//select_cnt 子模式控制：0 正常正常 | 1 校时 | 2 校分
reg set1,set2; //闹钟时钟分别设置
wire clk_10hz;  //10hz 时钟用做长按时钟。

wire[7:0] s_data1, s_data2;	//时钟与闹钟的秒
wire[7:0] m_data1, m_data2;	//时钟与闹钟的分
wire[7:0] h_data1, h_data2;	//时钟与闹钟的时

//分频器得到 10hz时钟用做设置时间
clok_div_10hz CLK10HZ (.clk_1khz(clk), .clk_10hz(clk_10hz), .rst(rst));

// C1-时钟 
clock C1 (.select_cnt(select_cnt), .s_clk(clk), .clk_10hz(clk_10hz), .set(set1), .s_data(s_data1), .m_data(m_data1), .h_data(h_data1), .en(en1), .rst(rst1));
// C2-闹钟 注：将C2的.s_clk输入从1'b0改成clk即可出现设置闹钟时指针仍在运行
clock C2 (.select_cnt(select_cnt), .s_clk(1'b0), .clk_10hz(clk_10hz), .set(set2), .s_data(s_data2), .m_data(m_data2), .h_data(h_data2), .en(en2), .rst(rst2));


always @ (posedge mode)
begin  //主模式切换
	if (mode_cnt == 1'b1)
		begin
		mode_cnt <= 1'b0;
		end
	else
		begin
		mode_cnt <= mode_cnt + 1'b1;
		end
end

always @ (posedge select, posedge mode)
begin  //子模式切换
	if (mode)
		select_cnt <= 2'b0;
	else if (select_cnt == 2'b10)
		select_cnt <= 2'b0;
	else
		select_cnt <= select_cnt + 1'b1;
end

always @ (*)
begin //根据模式执行状态
	if (mode_cnt == 1'b0)
		begin	//mode_cnt为0，执行时钟相关
			en1 <= 1'b1;	//时钟运行
			en2 <= 1'b0;	//闹钟不运行
			set1 <= set;   //时钟可调
			set2 <= 1'b0;  //闹钟不可调
			rst1 <= rst;	//时钟读取复位信号
			rst2 <= 1'b1;	//闹钟不读取复位信号
		end
	else
		begin	//mode_cnt为1，执行闹钟相关
			en1 <= 1'b1;	//时钟仍在运行
			en2 <= 1'b1;	//闹钟使能
			set1 <= 1'b0;  //时钟不可调
			set2 <= set;   //闹钟可调
			rst1 <= 1'b1;	//时钟不读取复位信号
			rst2 <= rst;	//闹钟读取复位信号
		end
end

always @ (*)
begin //闹钟响
	if (h_data1 == h_data2)
	begin
		if (m_data1 == m_data2)
			beep <= 1'd1; 	//beep信号置1
		else if (m_data1 == m_data2 + 1'b1)
			beep <= 1'b0;	//超过1分钟，beep置0
	end
	else 
		beep <= 1'b0;
	if (stop)
		beep <= 1'b0;	//手动置停
end


//数码管显示切换
assign s_data = mode_cnt ? 8'b0 : s_data1;
assign m_data = mode_cnt ? m_data2 : m_data1;
assign h_data = mode_cnt ? h_data2 : h_data1;


endmodule
 